package com.test.file.common.util;

import com.test.file.common.anno.FieldAttribute;
import com.test.file.common.constant.GlobalConstant;
import com.test.file.common.dto.FieldAttributeDto;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Author: chenKai
 * Date: 2023/2/1
 */
public class CommonUtil {
//    public static void checkArgsByString(String... strings) {
//        for (String string : strings) {
//            if (StringTools.isEmptyAll(string)) {
//                throw new BizException(BizCodeEnum.ARGS_ERROR);
//            }
//        }
//    }

    /**
     * 用于对excel时间的转换
     *
     * @param date
     * @return
     */
    public static Date excelChange(String date) {
        Calendar calendar = new GregorianCalendar(1900, 0, 0);
        int intDay = Integer.parseInt(date);
        return DateUtils.addDays(calendar.getTime(), intDay);
    }


    /**
     * 获取对象的注解信息
     * @param o
     * @return
     */
    public static List<FieldAttributeDto> getFiledDesc(Object o){
        List<FieldAttributeDto> filedList = Arrays.stream(o.getClass().getDeclaredFields())
                //对存在注解进行过滤
                .filter(f -> f.isAnnotationPresent(FieldAttribute.class))
                //对字段进行排序
                .sorted(Comparator.comparing(s -> s.getAnnotation(FieldAttribute.class).order()))
                //对私有字段进行暴力访问
                .peek(field -> field.setAccessible(true))
                .map(obj -> {
                    FieldAttributeDto fieldAttributeDto = new FieldAttributeDto();
                    fieldAttributeDto.setFiled(obj.getAnnotation(FieldAttribute.class).filed());
                    fieldAttributeDto.setDesc(obj.getAnnotation(FieldAttribute.class).desc());
                    fieldAttributeDto.setOrder(obj.getAnnotation(FieldAttribute.class).order());
                    fieldAttributeDto.setType(obj.getAnnotation(FieldAttribute.class).type());
                    fieldAttributeDto.setRequired(obj.getAnnotation(FieldAttribute.class).required());
                    fieldAttributeDto.setUnique(obj.getAnnotation(FieldAttribute.class).unique());
                    return fieldAttributeDto;
                }).collect(Collectors.toList());

        return filedList;
    }

    /**
     * 导出excel公共方法
     * @param request
     * @param response
     * @param sheetName 表名
     * @param list 数据列表
     * @param titleList 表头
     * @throws Exception
     */
    public static void exportExcel(HttpServletRequest request, HttpServletResponse response, String sheetName, List<Object> list, List<String> titleList) throws Exception {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFCellStyle style = wb.createCellStyle();
        style.setWrapText(true);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        XSSFSheet sheet = wb.createSheet(sheetName);
        XSSFRow headRow = sheet.createRow(0);
        //创建标题
        for (int i = 0; i < titleList.size() + 1; i++) {
            if (i == 0) {
                ExcelUtils.setValOnCenter(wb, sheet, 0, headRow, "序号", true);
                continue;
            }
            ExcelUtils.setValOnCenter(wb, sheet, i, headRow, titleList.get(i - 1), true);
        }


        Object o = list.get(0);
        List<FieldAttributeDto> filedList = getFiledDesc(o);

        int count = 0;
        for (Object item : list) {
            count++;
            XSSFRow row = sheet.createRow(count);
            for (int i = 0; i < filedList.size() + 1; i++) {
                if (i == 0) {
                    ExcelUtils.setValOnCenter(wb, sheet, i, row, count, true);
                    continue;
                }
                String value = "";
                if (GlobalConstant.DATE.equalsIgnoreCase(filedList.get(i -1).getType())){
                    Object invoke = item.getClass().getMethod("get" + getMethodName(filedList.get(i - 1).getFiled())).invoke(item);
                    value = DateTools.format((Date)invoke,DateTools.DATE_FORMAT2_8);
                }else {
                    value = item.getClass().getMethod("get" + getMethodName(filedList.get(i - 1).getFiled())).invoke(item).toString();
                }

                ExcelUtils.setValOnCenter(wb, sheet, i, row ,value, false);

            }
        }
        WriteExcel.write(request,response,wb,sheetName);
    }

    /**
     * excel导入公共方法  简单校验
     * @param sheet
     * @param repeatMap 与数据库重复数据检查
     * @return
     */
    public static Map<String,List<Object>> importExcel(Sheet sheet, Map<Object,Object> repeatMap, Object object) throws Exception {
        List<Object> successList = new ArrayList<>();
        List<Object> failList = new ArrayList<>();
        Map<String,List<Object>> result = new HashMap<>();
        result.put(GlobalConstant.SUCCESS,successList);
        result.put(GlobalConstant.FAIL,failList);

        //总条数
        int rowNum = sheet.getLastRowNum();

        //获取字段信息
        List<FieldAttributeDto> filedList = CommonUtil.getFiledDesc(object);
        for (int i = 0; i < rowNum; i++) {
            Object o = new Object();
            Row row = sheet.getRow(i);
            for (int j = 0; j < filedList.size(); j++) {
                Cell cell = row.getCell(j++);
                cell.setCellType(Cell.CELL_TYPE_STRING);
                String value = StringUtils.trim(cell.getStringCellValue());
                if (GlobalConstant.DATE.equalsIgnoreCase(filedList.get(i).getType())){
                    o.getClass().getMethod("set" + getMethodName(filedList.get(i).getFiled())).invoke(o,CommonUtil.excelChange(value));

                }else {
                    o.getClass().getMethod("set" + getMethodName(filedList.get(i).getFiled())).invoke(o,value);
                }
                if (j == filedList.size() - 1){
                    successList.add(o);
                }
            }
        }
        return result;
    }




    /**
     * 首字母大写(进行字母的ascii编码前移，效率是最高的)
     *
     * @param fieldName 需要转化的字符串
     */
    public static String getMethodName(String fieldName) throws Exception {
        char[] chars = fieldName.toCharArray();
        chars[0] = toUpperCase(chars[0]);
        return String.valueOf(chars);
    }

    /**
     * 字符转成大写
     *
     * @param c 需要转化的字符
     */
    public static char toUpperCase(char c) {
        if (97 <= c && c <= 122) {
            c ^= 32;
        }
        return c;
    }
}
